home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Database / TableView / TableViewController.m < prev    next >
Text File  |  1995-06-12  |  5KB  |  197 lines

  1. /* TableViewController.m:
  2.  * You may freely copy, distribute, and reuse the code in this example.
  3.  * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  4.  * fitness for any particular use.
  5.  *
  6.  * Written by: Mai Nguyen, NeXT Developer Support
  7.  *
  8.  *
  9.  */
  10. #import "TableViewController.h"
  11.  
  12. #define INSTALL_MODEL NXLocalizedString("Please install SybaseDemo.dbmodela or OracleDemo.dbmodela in your project.", NULL, "Notify user that the ascii model files must be installed in his project directory.")
  13.  
  14. /* Comment this line out if you want to run an Oracle version */
  15. #define    SYBASE_DEMO     1
  16.  
  17. @implementation TableViewController
  18. /*
  19. * Miscellaneous initialization tasks: connect to database, initialize
  20. * tableview, set up dbModule. 
  21. */ 
  22. -appDidInit:sender
  23. {
  24.     NXRect viewFrame;
  25.     
  26. #ifdef SYBASE_DEMO    
  27.     /* Notify the user if the database can't be found */
  28.     if (!(dbDatabase = [DBDatabase findDatabaseNamed:"SybaseDemo" 
  29.                     connect:YES])) {
  30.         NXRunAlertPanel(NULL,INSTALL_MODEL, "OK", NULL, NULL);
  31.         return self;
  32.     }
  33. #else
  34.     /* Notify the user if the database can't be found */
  35.     if (!(dbDatabase = [DBDatabase findDatabaseNamed:"OracleDemo" 
  36.                     connect:YES])) {
  37.         NXRunAlertPanel(NULL,INSTALL_MODEL, "OK", NULL, NULL);
  38.         return self;
  39.     }
  40. #endif
  41.  
  42.     [dbDatabase setDelegate:self];
  43.         
  44.         /* Install the tableview into the custom view */
  45.     [[dbTableView getFrame:&viewFrame] free];
  46.     dbTableView = [[DBTableView alloc] initFrame:&viewFrame];
  47.     [[window contentView] addSubview:dbTableView];
  48.     [dbTableView setHorizScrollerRequired:YES];
  49.     [dbTableView setVertScrollerRequired:YES];
  50.     [dbTableView setDelegate: self];
  51.  
  52. #ifdef SYBASE_DEMO
  53.     rootEntity = [dbDatabase entityNamed:"Author"];
  54. #else
  55.     rootEntity = [dbDatabase entityNamed:"Order"];
  56. #endif
  57.         /* Must initialize your dbModule */
  58.       dbModule = [[DBModule alloc] initDatabase:dbDatabase 
  59.                             entity:rootEntity];                    
  60.     dbFetchGroup = [dbModule rootFetchGroup];
  61.     [dbFetchGroup setDelegate:self];
  62. #ifdef SYBASE_DEMO
  63.     dbQualifier = [[DBQualifier alloc] initForEntity:[dbModule entity]
  64.                 fromDescription:"state = %s", "CA"];
  65. #else
  66.     dbQualifier = [[DBQualifier alloc] initForEntity:[dbModule entity]
  67.                 fromDescription:"customer.state = %s", "CA"];
  68. #endif        
  69.     [window disableFlushWindow];
  70.     [self initTableView];
  71.     [[window reenableFlushWindow] flushWindow];
  72.     
  73.     return self;
  74. }
  75. - showAll:sender
  76. {
  77.     [dbFetchGroup fetchContentsOf:[dbModule entity]
  78.                                             usingQualifier:dbQualifier];
  79.     [dbTableView display];
  80.  
  81.     return self;
  82. }
  83.  
  84. /* In order to replicate the Interface Builder functionality, one has to
  85.  * add an expression to the fetchgroup for each attribute and subattribute.
  86.  */
  87.  
  88. - addTableColumn:(const char *)label
  89. {
  90.     id newExpression;
  91.  
  92.     /* allocate a new expression, add it to the FetchGroup and add it */
  93.     /* to the TableView */
  94.     newExpression = [[DBExpression alloc] initForEntity:[dbModule entity]
  95.                 fromDescription:label];
  96.     [dbFetchGroup addExpression:newExpression];
  97.     [dbTableView  addColumn:newExpression withTitle:label];
  98.     return self;
  99. }
  100.  
  101.  
  102. /* Get all the attributes and subattributes from the defined table and
  103.  *    initialize the tableview accordingly.
  104.  */
  105. - initTableView
  106. {
  107.     int i, j, propCount, subpropCount;
  108.     id prop, subprop, subpropList;
  109.     char buffer[100];
  110.     id <DBEntities, DBTypes> theEntity;
  111.  
  112.       propList = [[List alloc] init];
  113.     [rootEntity getProperties: propList];
  114.     propCount = [propList count];
  115.  
  116.     for (i = 0; i < propCount; i++) {
  117.         prop = [propList objectAt:i];
  118.         theEntity = (id<DBTypes>)[prop propertyType];
  119.         if(! [theEntity isEntity]) {
  120.  
  121.             /* add top-level attribute */
  122.             [self addTableColumn:[prop name]];   /* defined above */
  123.         } else if ([prop isSingular]) {
  124.  
  125.             /* add all sub-attributes but skip sub-relationships.
  126.                Note that getting sub-attributes only work for
  127.                to-one relationship
  128.              */
  129.             subpropList  = [[List alloc] init];
  130.             
  131.             [theEntity getProperties:subpropList];
  132.             subpropCount = [subpropList count];
  133.             for (j = 0; j < subpropCount; j++) {
  134.                 subprop = [subpropList objectAt:j];
  135.                 if (![[subprop propertyType] isEntity]) {
  136.                 sprintf(buffer, "%s.%s", [prop name], [subprop name]);
  137.                 [self addTableColumn:buffer];   /* defined above */
  138.                 }
  139.             }
  140.             [subpropList free];        /* to prevent a memory leak */
  141.         }
  142.     }
  143.     
  144.         /* Making this association will make the fetchgroup
  145.          * become the tableview data source.
  146.          */
  147.     [dbFetchGroup makeAssociationFrom:nil to:dbTableView];
  148.         /*
  149.          * free property list which is no longer needed
  150.          */
  151.     [propList free];
  152.     [window makeKeyAndOrderFront:self];
  153.     return self;
  154. }
  155.  
  156.  
  157. /* Set the sort order before the actual fetch */
  158. - fetchGroupWillFetch: sender
  159. {
  160.     if( sortProp == nil) {
  161.     sortProp = [[dbTableView columnAt: 0] identifier];
  162.     }
  163.     [[sender recordList]
  164.     addRetrieveOrder: DB_AscendingOrder
  165.         for: sortProp];
  166.     return self;
  167. }
  168.  
  169. /* Find the new sort property every time the tableView column gets moved */
  170. - tableView:sender movedColumnFrom:(unsigned int) old to:(unsigned int) new
  171. {
  172.     sortProp = [[sender columnAt: new] identifier];
  173.     return [dbModule fetchAllRecords: self];
  174. }
  175.  
  176.  
  177.  
  178.  
  179. - free
  180. {
  181.     if (dbQualifier)
  182.         [dbQualifier free];
  183.     if (dbTableView)
  184.         [dbTableView free];
  185.     return [super free];
  186. }
  187.  
  188. /* DBDatabase delegate methods to log SQL queries  - Useful for debugging */
  189.  
  190. - (BOOL)db:aDb willEvaluateString:(const char*)aString usingBinder:aBinder
  191. {
  192.     fprintf(stderr, "SQL query:%s\n", aString);
  193.     return YES;
  194. }
  195.  
  196. @end
  197.